
#ifndef _NEBULA_SERVICE_BUILTINTASK_H_
#define _NEBULA_SERVICE_BUILTINTASK_H_

#include "TaskBase.h"
#include "Service.h"

namespace nebula { namespace sdk {

template<typename Type>
class BuiltinTaskBase : public TaskBase
{
	typedef BuiltinTaskBase<Type> this_type;
	typedef Type drived_type;

public:
	static ITask* Allocator(IService*)
	{
		return new Type();
	}

public:
	drived_type* Clone(IService* pservice)
	{
		drived_type* thisraw = dynamic_cast<drived_type*>(this);
		if (!thisraw)
			return 0;

		std::auto_ptr<drived_type> ret(static_cast<drived_type*>(Allocator(pservice)));

		if (ret->CopyUserData(thisraw) != NEBULA_ERR_SUCCESS)
			return 0;

		if (ret->SetTaskMeta(this->GetTaskMeta()->Clone()) != NEBULA_ERR_SUCCESS)
			return 0;

		return ret.release();
	}

public:
	virtual NEBULA_ERROR_CODE CopyUserData(const drived_type* rhs) = 0;
};

//////////////////////////////////////////////////////////////////////////
class PlainTextTask : public BuiltinTaskBase<PlainTextTask>
{
	typedef BuiltinTaskBase<PlainTextTask> base_type;
public:
	virtual NEBULA_ERROR_CODE Serialize  (std::ostream&);
	virtual NEBULA_ERROR_CODE UnSerialize(std::istream&);

public:
	virtual NEBULA_ERROR_CODE CopyUserData(const PlainTextTask* rhs);

public:
	const std::string& GetText() const;
	void SetText(const std::string&);
	void SwapText(std::string&);

private:
	std::string _data;
};

//////////////////////////////////////////////////////////////////////////
class MetaOnlyTask : public BuiltinTaskBase<MetaOnlyTask>
{
	typedef BuiltinTaskBase<MetaOnlyTask> base_type;
public:
	virtual NEBULA_ERROR_CODE Serialize(std::ostream& os);
	virtual NEBULA_ERROR_CODE UnSerialize(std::istream& is);

public:
	virtual NEBULA_ERROR_CODE CopyUserData(const MetaOnlyTask* rhs);
};


} } //end of nebula::sdk

#endif // end of _NEBULA_SERVICE_SAMPLETASKS_H_
